/**
 * 第一步
 * 新增实验设计
 */
import { FC, useEffect, useMemo, useState } from "react";
import {
  Layout,
  Divider,
  Row,
  Col,
  Form,
  Input,
  Select,
  Popover,
  Descriptions,
  Button,
} from "antd";
import { observer, inject } from "mobx-react";
import { useNavigate, useParams } from "react-router-dom";
import StepTop from "./StepTop";
import { createList, ROWWORD, RROWWORD, ReactionSlotName } from "../../utils";
import { ITStore } from "../../store";

import { ITExpTable, ITWorkbench } from "../../store/interfaces";

import "./index.less";

type TProp = {
  store: ITStore;
};

type TFinish = {
  id?: string;
  name: string;
  workbench: string;
  desc: string;
  expTable: string;
};

type TExpPopProp = {
  store: ITStore;
  data: ITExpTable;
};

type TplaneProp = {
  store: ITStore;
  data: ITExpTable;
  slotName: string;
};

const { Content } = Layout;
const { Option } = Select;

const WRAPWIDE = 80;
const WRAPHEIGHT = 80;

const Mplane: FC<TplaneProp | any> = inject("store")(
  observer(({ store, data, slotName }: TplaneProp) => {
    const {
      bottleStore: { allBottle },
      shelfStore: { allShelf },
    } = store;
    const { slotShelf, reactorSlotShelf } = data;
    const shelfInfo = useMemo(() => {
      let bottleName = "";
      if (slotName === ReactionSlotName) {
        const keys = Object.keys(reactorSlotShelf);
        bottleName = reactorSlotShelf[keys[0]].shelf;
      } else {
        const { shelf } = slotShelf[slotName] || {};
        if (shelf) {
          bottleName = shelf;
        }
      }
      let tmpShelfInfo: any = null;

      allShelf.some((item) => {
        if (item.name === bottleName) {
          tmpShelfInfo = item;
          return true;
        }
        return false;
      });
      return tmpShelfInfo;
    }, [slotShelf, reactorSlotShelf, slotName, allShelf]);

    const bottleInfo = useMemo(() => {
      let tmpBottleInfo: any = null;
      if (shelfInfo) {
        const { bottleType } = shelfInfo;

        allBottle.some((item) => {
          if (item.id === bottleType) {
            tmpBottleInfo = item;
            return true;
          }
          return false;
        });
      }
      return tmpBottleInfo;
    }, [shelfInfo, allBottle]);

    const { row, column, length } = shelfInfo || {};

    const { diameter = 0, shape } = bottleInfo || {};

    let planeRate = 1;
    if (length) {
      planeRate = WRAPWIDE / length;
    }

    const rowList = useMemo(() => {
      return createList(row);
    }, [row]);

    const colList = useMemo(() => {
      return createList(column);
    }, [column]);

    const bottlediameter = useMemo(() => {
      return Math.floor(planeRate * diameter) || 0;
    }, [diameter, planeRate]);

    const rowMarg = useMemo(() => {
      return Math.floor((WRAPHEIGHT - diameter * row) / (2 * row)) || 0;
    }, [diameter, row]);

    return (
      <div className="miniplane" style={{ width: WRAPWIDE }}>
        {rowList.map((item: number) => {
          return (
            <div
              key={item}
              className="row"
              style={{ marginTop: rowMarg, marginBottom: rowMarg }}
            >
              {colList.map((cItem: number) => {
                let colStyle = {
                  width: bottlediameter,
                  height: bottlediameter,
                  borderRadius: shape === "circular" ? bottlediameter : 8,
                };

                return (
                  <div key={cItem} className={`col`} style={colStyle}></div>
                );
              })}
            </div>
          );
        })}
      </div>
    );
  })
);

const PopoverExpCont: FC<TExpPopProp | any> = inject("store")(
  observer(({ store, data }: TExpPopProp) => {
    const {
      workbenchStore: { allWorkbench },
    } = store;
    const { workbench } = data;

    const currentWorkBench = useMemo(() => {
      let temp: ITWorkbench | null = null;
      allWorkbench.some((item) => {
        if (item.id === workbench) {
          temp = item;
          return true;
        }
        return false;
      });
      return temp;
    }, [workbench, allWorkbench]);

    if (!currentWorkBench) {
      return null;
    }

    const { row, column } = currentWorkBench;

    const rowNum = createList(row);
    const colNum = createList(column);

    return (
      <>
        <div className="wbexp">
          {rowNum.map((ritem: number) => {
            return (
              <div key={ritem} className="exprow">
                {colNum.map((citem: number) => {
                  const slotName = ROWWORD[ritem] + (citem + 1);
                  let hasMiniPlane = false;
                  const { slotShelf } = data;
                  if (slotShelf[slotName] || slotName === ReactionSlotName) {
                    hasMiniPlane = true;
                  }
                  return (
                    <div
                      key={citem}
                      className={`expcol ${hasMiniPlane ? "mnplane" : ""}`}
                    >
                      {!hasMiniPlane && (
                        <div className="exlabel">{slotName}</div>
                      )}
                      {hasMiniPlane && (
                        <Mplane data={data} slotName={slotName} />
                      )}
                    </div>
                  );
                })}
              </div>
            );
          })}
          {/* {rrowNum.map((ritem: number) => {
        return (
          <div key={ritem} className="exprow">
            {ccolNum.map((citem: number) => {
              const slotName = RROWWORD[ritem] + (citem + 1);
              return (
                <div key={citem} className="expcol">
                  <div className="exlabel">
                    {slotName}
                    {slotName === ReactionSlotName && <Mplane data={data} slotName={slotName} />}
                  </div>
                </div>
              );
            })}
          </div>
        );
      })} */}
        </div>
        <div style={{ clear: "both" }}></div>
      </>
    );
  })
);

const DesignerAddComp: FC<TProp | any> = inject("store")(
  observer(({ store }: TProp) => {
    const {
      languageStore: { lang },
      workbenchStore: { allWorkbench, getAllWorkbench, allExpTable },
      designerStore: {
        addEditDesignerLoading,
        addDesigner,
        currentDesigner,
        updateDesigner,
        allDesigner,
        getAllDesignerList,
      },
      userStore: { getUserInfo },
    } = store;
    const params = useParams();
    const { id } = params;
    const [form] = Form.useForm();
    const navigate = useNavigate();

    const [expTableOptions, setExpTableOptions] = useState<ITExpTable[]>([]);

    const [selectWorkbench, setSelectWorkbench] = useState<string>("");

    useEffect(() => {
      if (!allWorkbench.length) {
        getAllWorkbench();
      }
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    useEffect(() => {
      if (currentDesigner) {
        const { id, name, workbench, desc, expTable } = currentDesigner;
        form.setFieldsValue({
          id,
          name,
          workbench,
          desc,
          expTable,
        });
        setSelectWorkbench(workbench);
      } else {
        form.resetFields();
      }
    }, [currentDesigner, form]);

    useEffect(() => {
      if (allExpTable.length) {
        let templist: ITExpTable[] = [];
        allExpTable.forEach((item) => {
          if (item.workbench === selectWorkbench) {
            templist.push(item);
          }
        });
        setExpTableOptions(templist);
      }
    }, [selectWorkbench, allExpTable]);

    const onFinish = async (values: TFinish) => {
      const { id, expTable } = values;
      let result: any = null;
      if (id) {
        // 编辑
        result = await updateDesigner(values);
        navigate(`/designer/shelf/${id}`);
      } else {
        // 新增
        let extTableInfo: ITExpTable | any = null;

        allExpTable.some((item) => {
          if (item.id === expTable) {
            extTableInfo = item;
            return true;
          }
          return false;
        });

        const { slotShelf, reactorSlotShelf } = extTableInfo;

        const { id, ...addparam } = values;
        const userInfo = getUserInfo();
        result = await addDesigner(
          Object.assign(
            {},
            { ...addparam },
            { userInfo },
            { slotShelf, reactorSlotShelf }
          )
        );
        navigate(`/designer/shelf/${result.id}`);
      }
    };

    const workbenchChange = (data: string) => {
      form.setFieldsValue({
        expTable: "",
      });
      setSelectWorkbench(data);
    };

    const PopoverCont = ({ data }: any): JSX.Element => {
      const { name, row, column, rrow, rcolumn } = data;

      const rowNum = createList(row);
      const colNum = createList(column);
      const rrowNum = createList(rrow);
      const ccolNum = createList(rcolumn);

      return (
        <>
          <Descriptions bordered size="small">
            <Descriptions.Item label={lang["langname"]}>
              {name}
            </Descriptions.Item>
            <Descriptions.Item
              label={`${lang["langrow"]}(${lang["langreagent"]})`}
            >
              {row}
            </Descriptions.Item>
            <Descriptions.Item
              label={`${lang["langcolumn"]}(${lang["langreagent"]})`}
            >
              {column}
            </Descriptions.Item>
            <Descriptions.Item
              label={`${lang["langrow"]}(${lang["langreaction"]})`}
            >
              {rrow}
            </Descriptions.Item>
            <Descriptions.Item
              label={`${lang["langcolumn"]}(${lang["langreaction"]})`}
            >
              {rcolumn}
            </Descriptions.Item>
          </Descriptions>
          <div className="wbexp">
            {rowNum.map((ritem: number) => {
              return (
                <div key={ritem} className="exprow">
                  {colNum.map((citem: number) => {
                    return (
                      <div key={citem} className="expcol">
                        <div className="exlabel">
                          {ROWWORD[ritem]}
                          {citem + 1}
                        </div>
                      </div>
                    );
                  })}
                </div>
              );
            })}
            {rrowNum.map((ritem: number) => {
              return (
                <div key={ritem} className="exprow">
                  {ccolNum.map((citem: number) => {
                    return (
                      <div key={citem} className="expcol">
                        <div className="exlabel">
                          {RROWWORD[ritem]}
                          {citem + 1}
                        </div>
                      </div>
                    );
                  })}
                </div>
              );
            })}
          </div>
          <div style={{ clear: "both" }}></div>
        </>
      );
    };

    // const checkNameUnique = async (rule: any, value: any) => {
    //   let list: any = [];
      
    //   // 如果是在编辑，并且编辑后的名称相等，则不进行校验操作
    //   if (currentDesigner && currentDesigner.name === value) {
    //     return Promise.resolve();
    //   }


    //   if (!currentDesigner || currentDesigner.name !== value) {
    //     if (allDesigner && allDesigner.length) {
    //       list = allDesigner;
    //     } else {
    //       list = await getAllDesignerList();
    //     }

    //     return new Promise((resolve: any, reject) => {
    //       if (list && list.length) {
    //         list.some((item: any) => {
    //           if (item.name === value) {
    //             reject("The project names are repeated.");
    //           }
    //         });
    //       }
    //       resolve();
    //     });
    //   }
    // };

    return (
      <Row>
        <Col span={20}>
          <Form
            name="project"
            labelCol={{ span: 12 }}
            wrapperCol={{ span: 10 }}
            onFinish={onFinish}
            form={form}
          >
            <Form.Item label="" name="id" hidden>
              <Input />
            </Form.Item>
            <Form.Item
              label={lang["langprojectname"]}
              name="name"
              rules={[
                { required: true },
              ]}
            >
              <Input />
            </Form.Item>
            <Form.Item
              name="workbench"
              label={lang["langselectwb"]}
              rules={[{ required: true }]}
            >
              <Select onChange={workbenchChange} disabled={!!id}>
                {!!allWorkbench &&
                  !!allWorkbench.length &&
                  allWorkbench.map((item, index) => {
                    const { name, id } = item;
                    return (
                      <Option value={id} key={index}>
                        <Popover
                          placement="left"
                          content={<PopoverCont data={item} />}
                        >
                          <div>{name}</div>
                        </Popover>
                      </Option>
                    );
                  })}
              </Select>
            </Form.Item>
            <Form.Item name="expTable" label={lang["langselectexptable"]}>
              <Select disabled={!!id}>
                <Option value={""}>{lang["langempty"]}</Option>
                {!!expTableOptions &&
                  !!expTableOptions.length &&
                  expTableOptions.map((item, index) => {
                    const { name, id } = item;
                    return (
                      <Option value={id} key={index}>
                        <Popover
                          placement="left"
                          content={<PopoverExpCont data={item} />}
                        >
                          <div>{name}</div>
                        </Popover>
                      </Option>
                    );
                  })}
              </Select>
            </Form.Item>

            <Form.Item label={lang["langdescription"]} name="desc">
              <Input.TextArea />
            </Form.Item>
            <Form.Item wrapperCol={{ offset: 16, span: 8 }}>
              <Button
                type="primary"
                htmlType="submit"
                loading={addEditDesignerLoading}
              >
                {lang["langnext"]}
              </Button>
            </Form.Item>
          </Form>
        </Col>
        <Col span={4}></Col>
      </Row>
    );
  })
);

const DesignerAdd: FC<TProp | any> = ({ store }: TProp): JSX.Element => {
  const {
    designerStore: {
      getDesignerInfo,
      changeCurrentDesigner,
      changeCurrentSlotInfo,
      changeCurrentReactorSlotInfo,
      changeCurrentReagentsInfo,
      changeCurrentReagentorReagent,
    },
    workbenchStore: { getAllExpTable },
    bottleStore: { getAllBottle, allBottle },
    shelfStore: { allShelf, getAllShelf },
  } = store;
  const params = useParams();

  useEffect(() => {
    getAllExpTable();
    if (!allShelf.length) {
      getAllShelf();
    }
    if (!allBottle.length) {
      getAllBottle();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    const { id } = params;
    if (id) {
      getDesignerInfo({ id });
    } else {
      changeCurrentDesigner(null);
      changeCurrentSlotInfo({});
      changeCurrentReactorSlotInfo(null);
      changeCurrentReagentsInfo(null);
      changeCurrentReagentorReagent([]);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [params]);

  return (
    <Content className="mainLayout">
      <StepTop currentStep={0} />
      <Divider />
      <DesignerAddComp />
    </Content>
  );
};

export default inject("store")(observer(DesignerAdd));
